unit ovcrvexp;



{* ***** BEGIN LICENSE BLOCK *****                                            *}
{* Version: MPL 1.1                                                           *}
{*                                                                            *}
{* The contents of this file are subject to the Mozilla Public License        *}
{* Version 1.1 (the "License"); you may not use this file except in           *}
{* compliance with the License. You may obtain a copy of the License at       *}
{* http://www.mozilla.org/MPL/                                                *}
{*                                                                            *}
{* Software distributed under the License is distributed on an "AS IS" basis, *}
{* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License   *}
{* for the specific language governing rights and limitations under the       *}
{* License.                                                                   *}
{*                                                                            *}
{* The Original Code is TurboPower Orpheus                                    *}
{*                                                                            *}
{* The Initial Developer of the Original Code is TurboPower Software          *}
{*                                                                            *}
{* Portions created by TurboPower Software Inc. are Copyright (C)1995-2002    *}
{* TurboPower Software Inc. All Rights Reserved.                              *}
{*                                                                            *}
{* Contributor(s):                                                            *}
{*   Armin Biernaczyk                                                         *}
{*                                                                            *}
{* ***** END LICENSE BLOCK *****                                              *}


{ OvcRvExp
  Version: 0.0 Release 0 Build 31
  DATE OF GENERATION: 18-05-2002 20:37

  This unit was generated by Coco/R for Delphi (www.tetzel.com)  Any code in
  this file that you edit manually will be over-written when the file is
  regenerated.
}

interface
uses  SysUtils,Classes,OvcCoco,OvcRvExpDef;



const
maxT = 60;
type
  SymbolSet = array[0..maxT div setsize] of TBitSet;

  EOvcRvExp = class(Exception);
  TOvcRvExp = class;

  TOvcRvExpScanner = class(TCocoRScanner)
  private
    FOwner : TOvcRvExp;
    fLastCommentList : TCommentList;
procedure CheckLiteral(var Sym : integer);
function Equal(s : string) : boolean;
    function Comment : boolean;
  protected
    procedure NextCh; override;
  public
    constructor Create;
destructor Destroy; override;

    procedure Get(var sym : integer); override; // Gets next symbol from source file

    property CurrentSymbol;
    property NextSymbol;
    property OnStatusUpdate;
    property Owner : TOvcRvExp read fOwner write fOwner;
    property ScannerError;
    property SrcStream;
  end;  { TOvcRvExpScanner }

  TOvcRvExp = class(TCocoRGrammar)
  private
    { strictly internal variables }
    symSet : array[0..6] of SymbolSet; // symSet[0] = allSyncSyms
    fInternalGrammarComment : TCommentEvent;

    function GetMajorVersion : integer;
    function GetMinorVersion : integer;
    function GetRelease : integer;
    function GetBuild : integer;
    function GetBuildDate : TDateTime;
    function GetVersion : String;
    procedure SetVersion(const Value : string);
    function _In(var s : SymbolSet; x : integer) : boolean;
    procedure InitSymSet;

    {Production methods}
    procedure _BooleanLiteral (Parent: TOvcRvExpNode; var BooleanLiteral: TOvcRvExpBooleanLiteral);
    procedure _TimestampLiteral (Parent: TOvcRvExpNode;
                  var TimestampLiteral: TOvcRvExpTimestampLiteral);
    procedure _TimeLiteral (Parent: TOvcRvExpNode;
            var TimeLiteral: TOvcRvExpTimeLiteral);
    procedure _DateLiteral (Parent: TOvcRvExpNode;
             var DateLiteral: TOvcRvExpDateLiteral);
    procedure _StringLiteral (Parent: TOvcRvExpNode;
               var StringLiteral: TOvcRvExpStringLiteral);
    procedure _IntegerLiteral (Parent: TOvcRvExpNode;
                var IntegerLiteral: TOvcRvExpIntegerLiteral);
    procedure _FloatLiteral (Parent: TOvcRvExpNode;
              var FloatLiteral: TOvcRvExpFloatLiteral);
    procedure _WhenClause (Parent : TOvcRvExpNode;
            var WhenClause : TOvcRvExpWhenClause);
    procedure _WhenClauseList (Parent: TOvcRvExpNode;
               var WhenClauseList : TOvcRvExpWhenClauseList);
    procedure _CaseExpression (Parent: TOvcRvExpNode;
                var CaseExp: TOvcRvExpCaseExpression);
    procedure _ScalarFunction (Parent: TOvcRvExpNode;
                var Func: TOvcRvExpScalarFunc);
    procedure _Literal (Parent: TOvcRvExpNode;
         var Literal: TOvcRvExpLiteral);
    procedure _Factor (Parent: TOvcRvExpNode;
        var Factor : TOvcRvExpFactor;
        MulOp: TOvcRvExpMulOp);
    procedure _Term (Parent: TOvcRvExpNode; var Term : TOvcRvExpTerm; AddOp : TOvcRvExpAddOp);
    procedure _SimpleExpressionList (Parent: TOvcRvExpNode;
                      var SimpleExpressionList: TOvcRvExpSimpleExpressionList);
    procedure _IsTest (Parent: TOvcRvExpNode;
        var IsTest: TOvcRvExpIsTest);
    procedure _LikeClause (Parent: TOvcRvExpNode;
            var LikeClause: TOvcRvExpLikeClause;
            Negated: Boolean);
    procedure _InClause (Parent: TOvcRvExpNode;
          var InClause: TOvcRvExpInClause;
          Negated: Boolean);
    procedure _BetweenClause (Parent: TOvcRvExpNode;
               var BetweenClause: TOvcRvExpBetweenClause;
               Negated: Boolean);
    procedure _CondPrimary (Parent: TOvcRvExpNode;
             var CondPrimary : TOvcRvExpCondPrimary);
    procedure _CondFactor (Parent: TOvcRvExpNode;
            var CondFactor: TOvcRvExpCondFactor);
    procedure _CondTerm (Parent: TOvcRvExpNode;
          var CondTerm : TOvcRvExpCondTerm);
    procedure _CondExpList (Parent: TOvcRvExpNode;
                      var CondExpList: TOvcRvExpressionList);
    procedure _FieldRef (Parent: TOvcRvExpNode; var FieldRef: TOvcRvExpFieldRef);
    procedure _SimpleExpression (Parent: TOvcRvExpNode;
                  var SimpleExpression : TOvcRvExpSimpleExpression);
    procedure _Aggregate (Parent: TOvcRvExpNode; var Aggregate : TOvcRvExpAggregate);
    procedure _CondExp (Parent: TOvcRvExpNode;
         var CondExp: TOvcRvExpression);
    procedure _OvcRvExp;

  private
    FRootNode : TOvcRvExpression;

    procedure Init;
    procedure Final;


  protected
    { Protected Declarations }
    procedure Get; override;
    property InternalGrammarComment : TCommentEvent read fInternalGrammarComment write fInternalGrammarComment;
  public
    { Public Declarations }
    constructor Create(AOwner : TComponent); override;
    destructor Destroy; override;

    function ErrorStr(const ErrorCode : integer; const Data : string) : string; override;
    procedure Execute;
    function GetScanner : TOvcRvExpScanner;
    procedure Parse;

    property ErrorList;
    property ListStream;
    property SourceStream;
    property Successful;
    property MajorVersion : integer read GetMajorVersion;
    property MinorVersion : integer read GetMinorVersion;
    property Release : integer read GetRelease;
    property Build : integer read GetBuild;
    property BuildDate : TDateTime read GetBuildDate;

  public
    property RootNode : TOvcRvExpression read FRootNode write FRootNode;

  published
    { Published Declarations }
    property AfterParse;
    property AfterGenList;
    property BeforeGenList;
    property BeforeParse;
    property ClearSourceStream;
    property GenListWhen;
    property SourceFileName;
property Version : string read GetVersion write SetVersion;

    property OnCustomError;
    property OnError;
    property OnFailure;
    property OnStatusUpdate;
    property OnSuccess;
  end; { TOvcRvExp }

implementation

const
  EOFSYMB                       = 0;
  identSym                      = 1;
  integer_Sym                   = 2;
  floatSym                      = 3;
  SQLStringSym                  = 4;
  COUNTSym                      = 5;
  _lparenSym                    = 6;
  _starSym                      = 7;
  _rparenSym                    = 8;
  MINSym                        = 9;
  MAXSym                        = 10;
  SUMSym                        = 11;
  AVGSym                        = 12;
  _commaSym                     = 13;
  ORSym                         = 14;
  ANDSym                        = 15;
  NOTSym                        = 16;
  _equalSym                     = 17;
  _less_equalSym                = 18;
  _lessSym                      = 19;
  _greaterSym                   = 20;
  _greater_equalSym             = 21;
  _less_greaterSym              = 22;
  ISSym                         = 23;
  NULLSym                       = 24;
  TRUESym                       = 25;
  FALSESym                      = 26;
  UNKNOWNSym                    = 27;
  BETWEENSym                    = 28;
  LIKESym                       = 29;
  ESCAPESym                     = 30;
  INSym                         = 31;
  _plusSym                      = 32;
  _minusSym                     = 33;
  _bar_barSym                   = 34;
  _slashSym                     = 35;
  CASESym                       = 36;
  CHARACTER_underscoreLENGTHSym = 37;
  CHAR_underscoreLENGTHSym      = 38;
  LOWERSym                      = 39;
  UPPERSym                      = 40;
  POSITIONSym                   = 41;
  SUBSTRINGSym                  = 42;
  FROMSym                       = 43;
  FORSym                        = 44;
  TRIMSym                       = 45;
  LEADINGSym                    = 46;
  TRAILINGSym                   = 47;
  BOTHSym                       = 48;
  FORMATNUMBERSym               = 49;
  FORMATDATETIMESym             = 50;
  INTTOHEXSym                   = 51;
  EXTERNSym                     = 52;
  ELSESym                       = 53;
  ENDSym                        = 54;
  WHENSym                       = 55;
  THENSym                       = 56;
  DATESym                       = 57;
  TIMESym                       = 58;
  TIMESTAMPSym                  = 59;
  NOSYMB                        = 60;
  _noSym                        = NOSYMB;   {error token code}

{ --------------------------------------------------------------------------- }
{ Arbitrary Code from ATG file }
procedure TOvcRvExp.Init;
begin
  fRootNode := nil;
end;

procedure TOvcRvExp.Final;
begin
end;

(* End of Arbitrary Code *)


{ --------------------------------------------------------------------------- }
{ ---- implementation for TOvcRvExpScanner ---- }

procedure TOvcRvExpScanner.NextCh;
{ Return global variable ch
  -Changes
   04/2011, AB: Unicode compatibility }
begin
  LastInputCh := CurrInputCh;
  BufferPosition := BufferPosition + SizeOf(Char);
  SrcStream.Seek(BufferPosition,soFromBeginning);
  CurrInputCh := CurrentCh(BufferPosition);
  if (CurrInputCh = _EL) OR ((CurrInputCh = _LF) AND (LastInputCh <> _EL)) then
  begin
    CurrLine := CurrLine + 1;
    if Assigned(OnStatusUpdate) then
      OnStatusUpdate(Owner,IntToStr(CurrLine),CurrLine);
    StartOfLine := BufferPosition;
  end
end;  {NextCh}


function TOvcRvExpScanner.Comment : boolean;
var
  level : integer;
  CommentColumn : integer;
  CommentLine : integer;
  startLine : integer;
  oldLineStart : Integer;
  CommentStr : string;
begin
  level := 1;
  startLine := CurrLine;
  oldLineStart := StartOfLine;
  CommentStr := CharAt(BufferPosition);
  CommentColumn := BufferPosition - StartOfLine - 1;
  CommentLine := CurrLine;
//Result := false;
  if CurrInputCh = '/' then begin
    NextCh;
    CommentStr := CommentStr + CharAt(BufferPosition);
    if CurrInputCh = '/' then begin
      NextCh;
      CommentStr := CommentStr + CharAt(BufferPosition);
      while true do begin
        if CurrInputCh = CHR(13) then begin
          level := level - 1;
          NumEOLInComment := CurrLine - startLine;
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
          if level = 0 then begin
            Result := true;
            fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
            Exit;
          end;
        end else if CurrInputCh = _EF then begin
          Result := false;
          fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
          Exit;
        end else begin
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
        end;
      end; { WHILE TRUE }
    end else begin
      if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin
        CurrLine := CurrLine - 1;
        StartOfLine := oldLineStart
      end;
      BufferPosition := BufferPosition - SizeOf(Char);
      CurrInputCh := LastInputCh;
      //Result := false;
    end;
  end;

  //Result := false;
  if (CurrInputCh = '-') then begin
    NextCh;
    CommentStr := CommentStr + CharAt(BufferPosition);
    if (CurrInputCh = '-') then begin
      NextCh;
      CommentStr := CommentStr + CharAt(BufferPosition);
      while true do begin
        if (CurrInputCh = CHR(13)) then begin
          level := level - 1;
          NumEOLInComment := CurrLine - startLine;
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
          if level = 0 then begin
            Result := true;
            fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
            Exit;
          end;
        end else if CurrInputCh = _EF then begin
          Result := false;
          fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
          Exit;
        end else begin
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
        end;
      end; { WHILE TRUE }
    end else begin
      if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin
        CurrLine := CurrLine - 1;
        StartOfLine := oldLineStart
      end;
      BufferPosition := BufferPosition - SizeOf(Char);
      CurrInputCh := LastInputCh;
      //Result := false;
    end;
  end;
  Result := false;
  if (CurrInputCh = '/') then begin
    NextCh;
    CommentStr := CommentStr + CharAt(BufferPosition);
    if (CurrInputCh = '*') then begin
      NextCh;
      CommentStr := CommentStr + CharAt(BufferPosition);
      while true do begin
        if (CurrInputCh = '*') then begin
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
          if (CurrInputCh = '/') then begin
            level := level - 1;
            NextCh;
            CommentStr := CommentStr + CharAt(BufferPosition);
            if level = 0 then begin
              Result := true;
              fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
              Exit;
            end
          end
        end else if (CurrInputCh = '/') then begin
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
          if (CurrInputCh = '*') then begin
            level := level + 1;
            NextCh;
            CommentStr := CommentStr + CharAt(BufferPosition);
          end
        end else if CurrInputCh = _EF then begin
          Result := false;
          fLastCommentList.Add(CommentStr, CommentLine, CommentColumn);
          Exit;
        end else begin
          NextCh;
          CommentStr := CommentStr + CharAt(BufferPosition);
        end;
      end; { WHILE TRUE }
    end else begin
      if (CurrInputCh = _CR) OR (CurrInputCh = _LF) then begin
        CurrLine := CurrLine - 1;
        StartOfLine := oldLineStart
      end;
      BufferPosition := BufferPosition - SizeOf(Char);
      CurrInputCh := LastInputCh;
      Result := false;
    end;
  end;
end;  { Comment }


function TOvcRvExpScanner.Equal(s : string) : boolean;
  {-Changes
    04/2011, AB: Unicode compatibility }
var
  i : integer;
  q : Integer;
begin
  Result := false;
  if NextSymbol.Len <> Length(s) then
    Exit;
  i := 1;
  q := bpCurrToken;
  while i <= NextSymbol.Len do begin
    if CurrentCh(q) <> s[i] then
      Exit;
    inc(i);
    inc(q, SizeOf(Char));
  end;
  Result := true
end;  {Equal}


procedure TOvcRvExpScanner.CheckLiteral(var Sym : integer);
begin
  case CurrentCh(bpCurrToken) of
    'A': if Equal('AND') then
           sym := ANDSym
         else if Equal('AVG') then
           sym := AVGSym;

    'B': if Equal('BETWEEN') then
           sym := BETWEENSym
         else if Equal('BOTH') then
           sym := BOTHSym;

    'C': if Equal('CASE') then
           sym := CASESym
         else if Equal('CHARACTER_LENGTH') then
           sym := CHARACTER_underscoreLENGTHSym
         else if Equal('CHAR_LENGTH') then
           sym := CHAR_underscoreLENGTHSym
         else if Equal('COUNT') then
           sym := COUNTSym;

    'D': if Equal('DATE') then
           sym := DATESym;

    'E': if Equal('ELSE') then
           sym := ELSESym
         else if Equal('END') then
           sym := ENDSym
         else if Equal('ESCAPE') then
           sym := ESCAPESym
         else if Equal('EXTERN') then
           sym := EXTERNSym;

    'F': if Equal('FALSE') then
           sym := FALSESym
         else if Equal('FOR') then
           sym := FORSym
         else if Equal('FORMATDATETIME') then
           sym := FORMATDATETIMESym
         else if Equal('FORMATNUMBER') then
           sym := FORMATNUMBERSym
         else if Equal('FROM') then
           sym := FROMSym;

    'I': if Equal('IN') then
           sym := INSym
         else if Equal('INTTOHEX') then
           sym := INTTOHEXSym
         else if Equal('IS') then
           sym := ISSym;

    'L': if Equal('LEADING') then
           sym := LEADINGSym
         else if Equal('LIKE') then
           sym := LIKESym
         else if Equal('LOWER') then
           sym := LOWERSym;

    'M': if Equal('MAX') then
           sym := MAXSym
         else if Equal('MIN') then
           sym := MINSym;

    'N': if Equal('NOT') then
           sym := NOTSym
         else if Equal('NULL') then
           sym := NULLSym;

    'O': if Equal('OR') then
           sym := ORSym;

    'P': if Equal('POSITION') then
           sym := POSITIONSym;

    'S': if Equal('SUBSTRING') then
           sym := SUBSTRINGSym
         else if Equal('SUM') then
           sym := SUMSym;

    'T': if Equal('THEN') then
           sym := THENSym
         else if Equal('TIME') then
           sym := TIMESym
         else if Equal('TIMESTAMP') then
           sym := TIMESTAMPSym
         else if Equal('TRAILING') then
           sym := TRAILINGSym
         else if Equal('TRIM') then
           sym := TRIMSym
         else if Equal('TRUE') then
           sym := TRUESym;

    'U': if Equal('UNKNOWN') then
           sym := UNKNOWNSym
         else if Equal('UPPER') then
           sym := UPPERSym;

    'W': if Equal('WHEN') then
           sym := WHENSym;
  end;
end; {CheckLiteral}


procedure TOvcRvExpScanner.Get(var sym : integer);
var
  state : integer;
begin   {Get}
  while (CurrInputCh = ' ') OR
        ((CurrInputCh >= CHR(1)) AND (CurrInputCh <= ' ')) do
    NextCh;
  if ((CurrInputCh = '/') OR (CurrInputCh = '-') OR (CurrInputCh = '/')) AND Comment then
  begin
    Get(sym);
    exit;
  end;
  CurrentSymbol.pos := NextSymbol.Pos;
  NextSymbol.Pos := BufferPosition;
  CurrentSymbol.col := NextSymbol.Col;
  NextSymbol.Col := BufferPosition - StartOfLine;
  CurrentSymbol.line := NextSymbol.Line;
  NextSymbol.Line := CurrLine;
  CurrentSymbol.Len := NextSymbol.Len;
  NextSymbol.Len := 0;
  ContextLen := 0;
  if Ord(CurrInputCh)<=High(StartState^) then
    state := StartState[Ord(CurrInputCh)]
  else
    state := 1;
  bpCurrToken := BufferPosition;
  while true do
  begin
    NextCh;
    NextSymbol.Len := NextSymbol.Len + 1;
    if BufferPosition > SrcStream.Size then
    begin
      sym := EOFSYMB;
      CurrInputCh := _EF;
      BufferPosition := BufferPosition - SizeOf(Char);
      exit
    end;
    case state of
      1: if ((CurrInputCh = '!') OR
             (CurrInputCh >= '#') AND (CurrInputCh <= '$') OR
             (CurrInputCh >= '0') AND (CurrInputCh <= '9') OR
             (CurrInputCh >= '@') AND (CurrInputCh <= 'Z') OR
             (CurrInputCh = '\') OR
             (CurrInputCh >= '^') AND (CurrInputCh <= '{') OR
             (CurrInputCh >= '}')) then begin
         end else begin
           sym := identSym;
           CheckLiteral(sym);
           exit;
         end;
      2: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin
           state := 3;
         end else begin
           sym := _noSym;
           exit;
         end;
      3: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin
         end else begin
           sym := floatSym;
           exit;
         end;
      4: if ((CurrInputCh <= CHR(12)) OR
             (CurrInputCh >= CHR(14)) AND (CurrInputCh <= '&') OR
             (CurrInputCh >= '(')) then begin
         end else if (CurrInputCh = CHR(39)) then begin
           state := 6;
         end else begin
           sym := _noSym;
           exit;
         end;
      5: if ((CurrInputCh >= '0') AND (CurrInputCh <= '9')) then begin
         end else if (CurrInputCh = '.') then begin
           state := 2;
         end else begin
           sym := integer_Sym;
           exit;
         end;
      6: if (CurrInputCh = CHR(39)) then begin
           state := 4;
         end else begin
           sym := SQLStringSym;
           exit;
         end;
      7: begin
           sym := _lparenSym;
           exit;
         end;
      8: begin
           sym := _starSym;
           exit;
         end;
      9: begin
           sym := _rparenSym;
           exit;
         end;
     10: begin
           sym := _commaSym;
           exit;
         end;
     11: begin
           sym := _equalSym;
           exit;
         end;
     12: if (CurrInputCh = '=') then begin
           state := 13;
         end else if (CurrInputCh = '>') then begin
           state := 16;
         end else begin
           sym := _lessSym;
           exit;
         end;
     13: begin
           sym := _less_equalSym;
           exit;
         end;
     14: if (CurrInputCh = '=') then begin
           state := 15;
         end else begin
           sym := _greaterSym;
           exit;
         end;
     15: begin
           sym := _greater_equalSym;
           exit;
         end;
     16: begin
           sym := _less_greaterSym;
           exit;
         end;
     17: begin
           sym := _plusSym;
           exit;
         end;
     18: begin
           sym := _minusSym;
           exit;
         end;
     19: if (CurrInputCh = '|') then begin
           state := 20;
         end else begin
           sym := _noSym;
           exit;
         end;
     20: begin
           sym := _bar_barSym;
           exit;
         end;
     21: begin
           sym := _slashSym;
           exit;
         end;
     22: begin
           sym := EOFSYMB;
           CurrInputCh := #0;
           BufferPosition := BufferPosition - SizeOf(Char);
           exit;
         end;
     else begin
           sym := _noSym;
           EXIT;          // NextCh already done
         end;
    end;
  end;
end;  {Get}

constructor TOvcRvExpScanner.Create;
begin
  inherited;
  fLastCommentList := TCommentList.Create;
  CurrentCh := CapChAt;
  fStartState[  0] := 22; fStartState[  1] := 23; fStartState[  2] := 23; fStartState[  3] := 23;
  fStartState[  4] := 23; fStartState[  5] := 23; fStartState[  6] := 23; fStartState[  7] := 23;
  fStartState[  8] := 23; fStartState[  9] := 23; fStartState[ 10] := 23; fStartState[ 11] := 23;
  fStartState[ 12] := 23; fStartState[ 13] := 23; fStartState[ 14] := 23; fStartState[ 15] := 23;
  fStartState[ 16] := 23; fStartState[ 17] := 23; fStartState[ 18] := 23; fStartState[ 19] := 23;
  fStartState[ 20] := 23; fStartState[ 21] := 23; fStartState[ 22] := 23; fStartState[ 23] := 23;
  fStartState[ 24] := 23; fStartState[ 25] := 23; fStartState[ 26] := 23; fStartState[ 27] := 23;
  fStartState[ 28] := 23; fStartState[ 29] := 23; fStartState[ 30] := 23; fStartState[ 31] := 23;
  fStartState[ 32] := 23; fStartState[ 33] :=  1; fStartState[ 34] := 23; fStartState[ 35] :=  1;
  fStartState[ 36] :=  1; fStartState[ 37] := 23; fStartState[ 38] := 23; fStartState[ 39] :=  4;
  fStartState[ 40] :=  7; fStartState[ 41] :=  9; fStartState[ 42] :=  8; fStartState[ 43] := 17;
  fStartState[ 44] := 10; fStartState[ 45] := 18; fStartState[ 46] := 23; fStartState[ 47] := 21;
  fStartState[ 48] :=  5; fStartState[ 49] :=  5; fStartState[ 50] :=  5; fStartState[ 51] :=  5;
  fStartState[ 52] :=  5; fStartState[ 53] :=  5; fStartState[ 54] :=  5; fStartState[ 55] :=  5;
  fStartState[ 56] :=  5; fStartState[ 57] :=  5; fStartState[ 58] := 23; fStartState[ 59] := 23;
  fStartState[ 60] := 12; fStartState[ 61] := 11; fStartState[ 62] := 14; fStartState[ 63] := 23;
  fStartState[ 64] :=  1; fStartState[ 65] :=  1; fStartState[ 66] :=  1; fStartState[ 67] :=  1;
  fStartState[ 68] :=  1; fStartState[ 69] :=  1; fStartState[ 70] :=  1; fStartState[ 71] :=  1;
  fStartState[ 72] :=  1; fStartState[ 73] :=  1; fStartState[ 74] :=  1; fStartState[ 75] :=  1;
  fStartState[ 76] :=  1; fStartState[ 77] :=  1; fStartState[ 78] :=  1; fStartState[ 79] :=  1;
  fStartState[ 80] :=  1; fStartState[ 81] :=  1; fStartState[ 82] :=  1; fStartState[ 83] :=  1;
  fStartState[ 84] :=  1; fStartState[ 85] :=  1; fStartState[ 86] :=  1; fStartState[ 87] :=  1;
  fStartState[ 88] :=  1; fStartState[ 89] :=  1; fStartState[ 90] :=  1; fStartState[ 91] := 23;
  fStartState[ 92] :=  1; fStartState[ 93] := 23; fStartState[ 94] :=  1; fStartState[ 95] :=  1;
  fStartState[ 96] :=  1; fStartState[ 97] :=  1; fStartState[ 98] :=  1; fStartState[ 99] :=  1;
  fStartState[100] :=  1; fStartState[101] :=  1; fStartState[102] :=  1; fStartState[103] :=  1;
  fStartState[104] :=  1; fStartState[105] :=  1; fStartState[106] :=  1; fStartState[107] :=  1;
  fStartState[108] :=  1; fStartState[109] :=  1; fStartState[110] :=  1; fStartState[111] :=  1;
  fStartState[112] :=  1; fStartState[113] :=  1; fStartState[114] :=  1; fStartState[115] :=  1;
  fStartState[116] :=  1; fStartState[117] :=  1; fStartState[118] :=  1; fStartState[119] :=  1;
  fStartState[120] :=  1; fStartState[121] :=  1; fStartState[122] :=  1; fStartState[123] :=  1;
  fStartState[124] := 19; fStartState[125] :=  1; fStartState[126] :=  1; fStartState[127] :=  1;
  fStartState[128] :=  1; fStartState[129] :=  1; fStartState[130] :=  1; fStartState[131] :=  1;
  fStartState[132] :=  1; fStartState[133] :=  1; fStartState[134] :=  1; fStartState[135] :=  1;
  fStartState[136] :=  1; fStartState[137] :=  1; fStartState[138] :=  1; fStartState[139] :=  1;
  fStartState[140] :=  1; fStartState[141] :=  1; fStartState[142] :=  1; fStartState[143] :=  1;
  fStartState[144] :=  1; fStartState[145] :=  1; fStartState[146] :=  1; fStartState[147] :=  1;
  fStartState[148] :=  1; fStartState[149] :=  1; fStartState[150] :=  1; fStartState[151] :=  1;
  fStartState[152] :=  1; fStartState[153] :=  1; fStartState[154] :=  1; fStartState[155] :=  1;
  fStartState[156] :=  1; fStartState[157] :=  1; fStartState[158] :=  1; fStartState[159] :=  1;
  fStartState[160] :=  1; fStartState[161] :=  1; fStartState[162] :=  1; fStartState[163] :=  1;
  fStartState[164] :=  1; fStartState[165] :=  1; fStartState[166] :=  1; fStartState[167] :=  1;
  fStartState[168] :=  1; fStartState[169] :=  1; fStartState[170] :=  1; fStartState[171] :=  1;
  fStartState[172] :=  1; fStartState[173] :=  1; fStartState[174] :=  1; fStartState[175] :=  1;
  fStartState[176] :=  1; fStartState[177] :=  1; fStartState[178] :=  1; fStartState[179] :=  1;
  fStartState[180] :=  1; fStartState[181] :=  1; fStartState[182] :=  1; fStartState[183] :=  1;
  fStartState[184] :=  1; fStartState[185] :=  1; fStartState[186] :=  1; fStartState[187] :=  1;
  fStartState[188] :=  1; fStartState[189] :=  1; fStartState[190] :=  1; fStartState[191] :=  1;
  fStartState[192] :=  1; fStartState[193] :=  1; fStartState[194] :=  1; fStartState[195] :=  1;
  fStartState[196] :=  1; fStartState[197] :=  1; fStartState[198] :=  1; fStartState[199] :=  1;
  fStartState[200] :=  1; fStartState[201] :=  1; fStartState[202] :=  1; fStartState[203] :=  1;
  fStartState[204] :=  1; fStartState[205] :=  1; fStartState[206] :=  1; fStartState[207] :=  1;
  fStartState[208] :=  1; fStartState[209] :=  1; fStartState[210] :=  1; fStartState[211] :=  1;
  fStartState[212] :=  1; fStartState[213] :=  1; fStartState[214] :=  1; fStartState[215] :=  1;
  fStartState[216] :=  1; fStartState[217] :=  1; fStartState[218] :=  1; fStartState[219] :=  1;
  fStartState[220] :=  1; fStartState[221] :=  1; fStartState[222] :=  1; fStartState[223] :=  1;
  fStartState[224] :=  1; fStartState[225] :=  1; fStartState[226] :=  1; fStartState[227] :=  1;
  fStartState[228] :=  1; fStartState[229] :=  1; fStartState[230] :=  1; fStartState[231] :=  1;
  fStartState[232] :=  1; fStartState[233] :=  1; fStartState[234] :=  1; fStartState[235] :=  1;
  fStartState[236] :=  1; fStartState[237] :=  1; fStartState[238] :=  1; fStartState[239] :=  1;
  fStartState[240] :=  1; fStartState[241] :=  1; fStartState[242] :=  1; fStartState[243] :=  1;
  fStartState[244] :=  1; fStartState[245] :=  1; fStartState[246] :=  1; fStartState[247] :=  1;
  fStartState[248] :=  1; fStartState[249] :=  1; fStartState[250] :=  1; fStartState[251] :=  1;
  fStartState[252] :=  1; fStartState[253] :=  1; fStartState[254] :=  1; fStartState[255] :=  1;
end; {Create}

destructor TOvcRvExpScanner.Destroy;
begin
  if Assigned(fLastCommentList) then
  begin
    fLastCommentList.Free;
    fLastCommentList := NIL;
  end;
  inherited;
end;

{ --------------------------------------------------------------------------- }
{ ---- implementation for TOvcRvExp ---- }

constructor TOvcRvExp.Create(AOwner : TComponent);
begin
  inherited;
  Scanner := TOvcRvExpScanner.Create;
  GetScanner.Owner := self;
  FRootNode := nil;
  InitSymSet;
end; {Create}


destructor TOvcRvExp.Destroy;
begin
  Scanner.Free;
  inherited;
end; {Destroy}


function TOvcRvExp.ErrorStr(const ErrorCode : integer; const Data : string) : string;
begin
  case ErrorCode of
     0 : Result := 'EOF expected';
     1 : Result := 'ident expected';
     2 : Result := 'integer_ expected';
     3 : Result := 'float expected';
     4 : Result := 'SQLString expected';
     5 : Result := '"COUNT" expected';
     6 : Result := '"(" expected';
     7 : Result := '"*" expected';
     8 : Result := '")" expected';
     9 : Result := '"MIN" expected';
    10 : Result := '"MAX" expected';
    11 : Result := '"SUM" expected';
    12 : Result := '"AVG" expected';
    13 : Result := '"," expected';
    14 : Result := '"OR" expected';
    15 : Result := '"AND" expected';
    16 : Result := '"NOT" expected';
    17 : Result := '"=" expected';
    18 : Result := '"<=" expected';
    19 : Result := '"<" expected';
    20 : Result := '">" expected';
    21 : Result := '">=" expected';
    22 : Result := '"<>" expected';
    23 : Result := '"IS" expected';
    24 : Result := '"NULL" expected';
    25 : Result := '"TRUE" expected';
    26 : Result := '"FALSE" expected';
    27 : Result := '"UNKNOWN" expected';
    28 : Result := '"BETWEEN" expected';
    29 : Result := '"LIKE" expected';
    30 : Result := '"ESCAPE" expected';
    31 : Result := '"IN" expected';
    32 : Result := '"+" expected';
    33 : Result := '"-" expected';
    34 : Result := '"||" expected';
    35 : Result := '"/" expected';
    36 : Result := '"CASE" expected';
    37 : Result := '"CHARACTER_LENGTH" expected';
    38 : Result := '"CHAR_LENGTH" expected';
    39 : Result := '"LOWER" expected';
    40 : Result := '"UPPER" expected';
    41 : Result := '"POSITION" expected';
    42 : Result := '"SUBSTRING" expected';
    43 : Result := '"FROM" expected';
    44 : Result := '"FOR" expected';
    45 : Result := '"TRIM" expected';
    46 : Result := '"LEADING" expected';
    47 : Result := '"TRAILING" expected';
    48 : Result := '"BOTH" expected';
    49 : Result := '"FORMATNUMBER" expected';
    50 : Result := '"FORMATDATETIME" expected';
    51 : Result := '"INTTOHEX" expected';
    52 : Result := '"EXTERN" expected';
    53 : Result := '"ELSE" expected';
    54 : Result := '"END" expected';
    55 : Result := '"WHEN" expected';
    56 : Result := '"THEN" expected';
    57 : Result := '"DATE" expected';
    58 : Result := '"TIME" expected';
    59 : Result := '"TIMESTAMP" expected';
    60 : Result := 'not expected';
    61 : Result := 'invalid BooleanLiteral';
    62 : Result := 'invalid WhenClause';
    63 : Result := 'invalid CaseExpression';
    64 : Result := 'invalid ScalarFunction';
    65 : Result := 'invalid Literal';
    66 : Result := 'invalid Factor';
    67 : Result := 'invalid IsTest';
    68 : Result := 'invalid CondPrimary';
    69 : Result := 'invalid CondPrimary';
    70 : Result := 'invalid CondPrimary';
    71 : Result := 'invalid Aggregate';
   200 : Result := 'Text after end of valid expression';

  else
    if Assigned(OnCustomError) then
      Result := OnCustomError(Self, ErrorCode, Data)
    else
    begin
      Result := 'Error: ' + IntToStr(ErrorCode);
      if Trim(Data) > '' then
        Result := Result + ' (' + Data + ')';
    end;
  end;  {case nr}
end; {ErrorStr}


procedure TOvcRvExp.Execute;
begin
  ClearErrors;
  ListStream.Clear;
  Extra := 1;

  { if there is a file name then load the file }
  if Trim(SourceFileName) <> '' then
  begin
    GetScanner.SrcStream.Clear;
    GetScanner.SrcStream.LoadFromFile(SourceFileName);
  end;

  { install error reporting procedure }
  GetScanner.ScannerError := StoreError;

  if Assigned(OnStatusUpdate) then
    OnStatusUpdate(Self,'parsing source',-1);

  { instigate the compilation }
  if Assigned(BeforeParse) then
    BeforeParse(Self);
  Parse;
  if Assigned(AfterParse) then
    AfterParse(Self);

  { generate the source listing to the ListStream }
  if (GenListWhen = glAlways) OR ((GenListWhen = glOnError) AND (ErrorList.Count > 0)) then
    GenerateListing;
  if ClearSourceStream then
    GetScanner.SrcStream.Clear;
  ListStream.Position := 0;  // goto the beginning of the stream
  if Successful AND Assigned(OnSuccess) then
    OnSuccess(Self);
  if (NOT Successful) AND Assigned(OnFailure) then
    OnFailure(Self, ErrorList.Count);
end;  {Execute}


procedure TOvcRvExp.Get;
begin
  repeat
    if GetScanner.fLastCommentList.Count > 0 then
    begin
      if Assigned(fInternalGrammarComment) then
        fInternalGrammarComment(Self,GetScanner.fLastCommentList);
      GetScanner.fLastCommentList.Clear;
    end;

    GetScanner.Get(fCurrentInputSymbol);
    if fCurrentInputSymbol <= maxT then
      errDist := errDist + 1;
  until fCurrentInputSymbol <= maxT;
end;  {Get}


function TOvcRvExp.GetScanner : TOvcRvExpScanner;
begin
  Result := Scanner as TOvcRvExpScanner;
end; {GetScanner}


function TOvcRvExp._In(var s : SymbolSet; x : integer) : boolean;
begin
  _In := x mod setsize in s[x div setsize];
end;  {_In}


procedure TOvcRvExp._BooleanLiteral
  (Parent: TOvcRvExpNode; var BooleanLiteral: TOvcRvExpBooleanLiteral);
begin
  BooleanLiteral := TOvcRvExpBooleanLiteral.Create(Parent);
  if fCurrentInputSymbol = TRUESym then begin
    Get;
    BooleanLiteral.Value := True;
  end else if fCurrentInputSymbol = FALSESym then
    Get
  else
    SynError(61);
end;


procedure TOvcRvExp._TimestampLiteral
  (Parent: TOvcRvExpNode; var TimestampLiteral: TOvcRvExpTimestampLiteral);
begin
  TimestampLiteral := TOvcRvExpTimestampLiteral.Create(Parent);
  Expect(TIMESTAMPSym);
  Expect(SQLStringSym);
  TimestampLiteral.Value := LexString;
end;


procedure TOvcRvExp._TimeLiteral
  (Parent: TOvcRvExpNode; var TimeLiteral: TOvcRvExpTimeLiteral);
begin
  TimeLiteral := TOvcRvExpTimeLiteral.Create(Parent);
  Expect(TIMESym);
  Expect(SQLStringSym);
  TimeLiteral.Value := LexString;
end;


procedure TOvcRvExp._DateLiteral
  (Parent: TOvcRvExpNode; var DateLiteral: TOvcRvExpDateLiteral);
begin
  DateLiteral := TOvcRvExpDateLiteral.Create(Parent);
  Expect(DATESym);
  Expect(SQLStringSym);
  DateLiteral.Value := LexString;
end;


procedure TOvcRvExp._StringLiteral
  (Parent: TOvcRvExpNode; var StringLiteral: TOvcRvExpStringLiteral);
begin
  StringLiteral := TOvcRvExpStringLiteral.Create(Parent);
  Expect(SQLStringSym);
  StringLiteral.Value := LexString;
end;


procedure TOvcRvExp._IntegerLiteral
  (Parent: TOvcRvExpNode; var IntegerLiteral: TOvcRvExpIntegerLiteral);
begin
  IntegerLiteral := TOvcRvExpIntegerLiteral.Create(Parent);
  Expect(integer_Sym);
  IntegerLiteral.Value := LexString;
end;


procedure TOvcRvExp._FloatLiteral
  (Parent: TOvcRvExpNode; var FloatLiteral: TOvcRvExpFloatLiteral);
begin
  FloatLiteral := TOvcRvExpFloatLiteral.Create(Parent);
  Expect(floatSym);
  FloatLiteral.Value := LexString;
end;


procedure TOvcRvExp._WhenClause
  (Parent: TOvcRvExpNode; var WhenClause: TOvcRvExpWhenClause);
var
  CondExp : TOvcRvExpression;
  Exp     : TOvcRvExpSimpleExpression;
begin
  WhenClause := TOvcRvExpWhenClause.Create(Parent);
  Expect(WHENSym);
  _CondExp(WhenClause, CondExp);
  WhenClause.WhenExp := CondExp;
  Expect(THENSym);
  if fCurrentInputSymbol = NULLSym then
    Get
  else if _In(symSet[1], fCurrentInputSymbol) then begin
    _SimpleExpression(WhenClause, Exp);
    WhenClause.ThenExp := Exp;
  end else
    SynError(62);
end;


procedure TOvcRvExp._WhenClauseList
  (Parent: TOvcRvExpNode; var WhenClauseList: TOvcRvExpWhenClauseList);
var
  WhenClause:  TOvcRvExpWhenClause;
begin
  WhenClauseList := TOvcRvExpWhenClauseList.Create(Parent);
  _WhenClause(WhenClauseList, WhenClause);
  WhenClauseList.AddWhenClause(WhenClause);
  while (fCurrentInputSymbol = WHENSym) do begin
    _WhenClause(WhenClauseList, WhenClause);
    WhenClauseList.AddWhenClause(WhenClause);
  end;
end;


procedure TOvcRvExp._CaseExpression
  (Parent: TOvcRvExpNode; var CaseExp: TOvcRvExpCaseExpression);
var
  WhenClauseList:  TOvcRvExpWhenClauseList;
  Exp           :  TOvcRvExpSimpleExpression;
begin
  CaseExp := TOvcRvExpCaseExpression.Create(Parent);
  _WhenClauseList(CaseExp, WhenClauseList);
  CaseExp.WhenClauseList := WhenClauseList;
  if fCurrentInputSymbol = ELSESym then begin
    Get;
    if fCurrentInputSymbol = NULLSym then
      Get
    else if _In(symSet[1], fCurrentInputSymbol) then begin
      _SimpleExpression(CaseExp, Exp);
      CaseExp.ElseExp := Exp;
    end else
      SynError(63);
  end;
  Expect(ENDSym);
end;


procedure TOvcRvExp._ScalarFunction
  (Parent: TOvcRvExpNode; var Func: TOvcRvExpScalarFunc);
var
  CondExp : TOvcRvExpression;
  Exp     : TOvcRvExpSimpleExpression;
  ExpList : TOvcRvExpressionList;
  CaseExp : TOvcRvExpCaseExpression;
begin
  Func := TOvcRvExpScalarFunc.Create(Parent);
  case fCurrentInputSymbol of
    CASESym : begin
      Get;
      _CaseExpression(Func, CaseExp);
      Func.CaseExp := CaseExp;
      Func.SQLFunction := sfCase;
    end;
    CHARACTER_underscoreLENGTHSym, CHAR_underscoreLENGTHSym : begin
      if fCurrentInputSymbol = CHARACTER_underscoreLENGTHSym then begin
        Get;
      end else begin
        Get;
      end;
      Expect(_lparenSym);
      _SimpleExpression(Func, Exp);
      Expect(_rparenSym);
      Func.SQLFunction := sfCharLen;
      Func.Arg1 := Exp;
    end;
    LOWERSym : begin
      Get;
      Expect(_lparenSym);
      _SimpleExpression(Func, Exp);
      Expect(_rparenSym);
      Func.SQLFunction := sfLower;
      Func.Arg1 := Exp;
    end;
    UPPERSym : begin
      Get;
      Expect(_lparenSym);
      _SimpleExpression(Func, Exp);
      Expect(_rparenSym);
      Func.SQLFunction := sfUpper;
      Func.Arg1 := Exp;
    end;
    POSITIONSym : begin
      Get;
      Expect(_lparenSym);
      _SimpleExpression(Func, Exp);
      Func.SQLFunction := sfPosition;
      Func.Arg1 := Exp;
      Expect(_commaSym);
      _SimpleExpression(Func, Exp);
      Func.Arg2 := Exp;
      Expect(_rparenSym);
    end;
    SUBSTRINGSym : begin
      Get;
      Expect(_lparenSym);
      _SimpleExpression(Func, Exp);
      Func.SQLFunction := sfSubstring;
      Func.Arg1 := Exp;
      Expect(FROMSym);
      _SimpleExpression(Func, Exp);
      Func.Arg2 := Exp;
      if fCurrentInputSymbol = FORSym then begin
        Get;
        _SimpleExpression(Func, Exp);
        Func.Arg3 := Exp;
      end;
      Expect(_rparenSym);
    end;
    TRIMSym : begin
      Get;
      Expect(_lparenSym);
      Func.SQLFunction := sfTrim;
      Func.LTB := ltbBoth;
      if (fCurrentInputSymbol = LEADINGSym) OR
         (fCurrentInputSymbol = TRAILINGSym) OR
         (fCurrentInputSymbol = BOTHSym) then begin
        if fCurrentInputSymbol = LEADINGSym then begin
          Get;
          Func.LTB := ltbLeading;
        end else if fCurrentInputSymbol = TRAILINGSym then begin
          Get;
          Func.LTB := ltbTrailing;
        end else begin
          Get;
        end;
      end;
      if _In(symSet[1], fCurrentInputSymbol) then begin
        _SimpleExpression(Func, Exp);
        Func.Arg1 := Exp;
      end;
      if fCurrentInputSymbol = FROMSym then begin
        Get;
        _SimpleExpression(Func, Exp);
        Func.Arg2 := Exp;
      end;
      Expect(_rparenSym);
    end;
    FORMATNUMBERSym : begin
      Get;
      Expect(_lparenSym);
      Func.SQLFunction := sfFormatFloat;
      _SimpleExpression(Func, Exp);
      Func.Arg1 := Exp;
      Expect(_commaSym);
      _SimpleExpression(Func, Exp);
      Func.Arg2 := Exp;
      if fCurrentInputSymbol = _commaSym then begin
        Get;
        _CondExp(Func, CondExp);
        Func.CondArg1 := CondExp;
      end;
      Expect(_rparenSym);
    end;
    FORMATDATETIMESym : begin
      Get;
      Expect(_lparenSym);
      Func.SQLFunction := sfFormatDateTime;
      _SimpleExpression(Func, Exp);
      Func.Arg1 := Exp;
      Expect(_commaSym);
      _SimpleExpression(Func, Exp);
      Func.Arg2 := Exp;
      Expect(_rparenSym);
    end;
    INTTOHEXSym : begin
      Get;
      Expect(_lparenSym);
      Func.SQLFunction := sfIntToHex;
      _SimpleExpression(Func, Exp);
      Func.Arg1 := Exp;
      if fCurrentInputSymbol = _commaSym then begin
        Get;
        _SimpleExpression(Func, Exp);
        Func.Arg2 := Exp;
      end;
      Expect(_rparenSym);
    end;
    EXTERNSym : begin
      Get;
      Expect(_lparenSym);
      Func.SQLFunction := sfExtern;
      _CondExpList(Func, ExpList);
      Func.ExpList := ExpList;
      Expect(_rparenSym);
    end;
    else
      SynError(64);
  end;
end;


procedure TOvcRvExp._Literal
  (Parent: TOvcRvExpNode; var Literal: TOvcRvExpLiteral);
var
  FloatLiteral     :  TOvcRvExpFloatLiteral;
  IntegerLiteral   :  TOvcRvExpIntegerLiteral;
  StringLiteral    :  TOvcRvExpStringLiteral;
  DateLiteral      :  TOvcRvExpDateLiteral;
  TimeLiteral      :  TOvcRvExpTimeLiteral;
  TimestampLiteral :  TOvcRvExpTimestampLiteral;
  BooleanLiteral   :  TOvcRvExpBooleanLiteral;
begin
  Literal := TOvcRvExpLiteral.Create(Parent);
  case fCurrentInputSymbol of
    floatSym : begin
      _FloatLiteral(Literal, FloatLiteral);
      Literal.FloatLiteral := FloatLiteral;
    end;
    integer_Sym : begin
      _IntegerLiteral(Literal, IntegerLiteral);
      Literal.IntegerLiteral := IntegerLiteral;
    end;
    SQLStringSym : begin
      _StringLiteral(Literal, StringLiteral);
      Literal.StringLiteral := StringLiteral;
    end;
    DATESym : begin
      _DateLiteral(Literal, DateLiteral);
      Literal.DateLiteral := DateLiteral;
    end;
    TIMESym : begin
      _TimeLiteral(Literal, TimeLiteral);
      Literal.TimeLiteral := TimeLiteral;
    end;
    TIMESTAMPSym : begin
      _TimestampLiteral(Literal, TimestampLiteral);
      Literal.TimestampLiteral := TimestampLiteral;
    end;
    TRUESym, FALSESym : begin
      _BooleanLiteral(Literal, BooleanLiteral);
      Literal.BooleanLiteral := BooleanLiteral;
    end;
    else
      SynError(65);
  end;
end;


procedure TOvcRvExp._Factor
  (Parent: TOvcRvExpNode; var Factor: TOvcRvExpFactor; MulOp: TOvcRvExpMulOp);
var
  FieldRef :  TOvcRvExpFieldRef;
  CondExp  :  TOvcRvExpression;
  Literal  :  TOvcRvExpLiteral;
  Agg      :  TOvcRvExpAggregate;
  Func     :  TOvcRvExpScalarFunc;
begin
  Factor :=  TOvcRvExpFactor.Create(Parent);
  Factor.MulOp := MulOp;
  if fCurrentInputSymbol = _minusSym then begin
    Get;
    Factor.UnaryMinus := True;
  end;
  if fCurrentInputSymbol = _lparenSym then begin
    Get;
    _CondExp(Factor, CondExp);
    Factor.CondExp := CondExp;
    Expect(_rparenSym);
  end else if fCurrentInputSymbol = identSym then begin
    _FieldRef(Factor, FieldRef);
    Factor.FieldRef := FieldRef;
  end else if _In(symSet[2], fCurrentInputSymbol) then begin
    _Literal(Factor, Literal);
    Factor.Literal := Literal;
  end else if (fCurrentInputSymbol = COUNTSym) OR
              (fCurrentInputSymbol = MINSym) OR
              (fCurrentInputSymbol = MAXSym) OR
              (fCurrentInputSymbol = SUMSym) OR
              (fCurrentInputSymbol = AVGSym) then begin
    _Aggregate(Factor, Agg);
    Factor.Aggregate := Agg;
  end else if _In(symSet[3], fCurrentInputSymbol) then begin
    _ScalarFunction(Factor, Func);
    Factor.ScalarFunc := Func;
  end else
    SynError(66);
end;


procedure TOvcRvExp._Term
  (Parent: TOvcRvExpNode; var Term: TOvcRvExpTerm; AddOp: TOvcRvExpAddOp);
var
  Factor :  TOvcRvExpFactor;
  MO     :  TOvcRvExpMulOp;
begin
  Term := TOvcRvExpTerm.Create(Parent);
  Term.AddOp := AddOp;
  _Factor(Term, Factor, moMul);
  Term.AddFactor(Factor);
  while (fCurrentInputSymbol = _starSym) OR
        (fCurrentInputSymbol = _slashSym) do begin
    if fCurrentInputSymbol = _starSym then begin
      Get;
      MO := moMul;
    end else begin
      Get;
      MO := moDiv;
    end;
    _Factor(Term, Factor, MO);
    Term.AddFactor(Factor);
  end;
end;


procedure TOvcRvExp._SimpleExpressionList
  (Parent: TOvcRvExpNode; var SimpleExpressionList: TOvcRvExpSimpleExpressionList);
var
  SimpleExpression:  TOvcRvExpSimpleExpression;
begin
  SimpleExpressionList := TOvcRvExpSimpleExpressionList.Create(Parent);
  _SimpleExpression(SimpleExpressionList, SimpleExpression);
  SimpleExpressionList.AddExpression(SimpleExpression);
  while fCurrentInputSymbol = _commaSym do begin
    Get;
    _SimpleExpression(SimpleExpressionList, SimpleExpression);
    SimpleExpressionList.AddExpression(SimpleExpression);
  end;
end;


procedure TOvcRvExp._IsTest
  (Parent: TOvcRvExpNode; var IsTest: TOvcRvExpIsTest);
begin
  Expect(ISSym);
  IsTest := TOvcRvExpIsTest.Create(Parent);
  if fCurrentInputSymbol = NOTSym then begin
    Get;
    IsTest.UnaryNot := True;
  end;
  if fCurrentInputSymbol = NULLSym then begin
    Get;
    IsTest.IsOp := ioNull;
  end else if fCurrentInputSymbol = TRUESym then begin
    Get;
    IsTest.IsOp := ioTrue;
  end else if fCurrentInputSymbol = FALSESym then begin
    Get;
    IsTest.IsOp := ioFalse;
  end else if fCurrentInputSymbol = UNKNOWNSym then begin
    Get;
    IsTest.IsOp := ioUnknown;
  end else
    SynError(67);
end;


procedure TOvcRvExp._LikeClause
  (Parent: TOvcRvExpNode; var LikeClause: TOvcRvExpLikeClause; Negated: Boolean);
var
  SimpleExpression: TOvcRvExpSimpleExpression;
begin
  LikeClause := TOvcRvExpLikeClause.Create(Parent);
  LikeClause.Negated := Negated;
  Expect(LIKESym);
  _SimpleExpression(LikeClause, SimpleExpression);
  LikeClause.SimpleExp := SimpleExpression;
  if (fCurrentInputSymbol = ESCAPESym) then begin
    Get;
    _SimpleExpression(LikeClause, SimpleExpression);
    LikeClause.EscapeExp := SimpleExpression;
  end;
end;


procedure TOvcRvExp._InClause
  (Parent: TOvcRvExpNode; var InClause: TOvcRvExpInClause; Negated: Boolean);
var
  SimpleExpressionList:  TOvcRvExpSimpleExpressionList;
begin
  InClause := TOvcRvExpInClause.Create(Parent);
  InClause.Negated := Negated;
  Expect(INSym);
  Expect(_lparenSym);
  _SimpleExpressionList(InClause, SimpleExpressionList);
  Inclause.SimpleExpList := SimpleExpressionList;
  Expect(_rparenSym);
end;


procedure TOvcRvExp._BetweenClause
  (Parent: TOvcRvExpNode; var BetweenClause: TOvcRvExpBetweenClause; Negated: Boolean);
var
  SimpleExpression:  TOvcRvExpSimpleExpression;
begin
  BetweenClause := TOvcRvExpBetweenClause.Create(Parent);
  BetweenClause.Negated := Negated;
  Expect(BETWEENSym);
  _SimpleExpression(BetweenClause, SimpleExpression);
  BetweenClause.SimpleLow := SimpleExpression;
  Expect(ANDSym);
  _SimpleExpression(BetweenClause, SimpleExpression);
  BetweenClause.SimpleHigh := SimpleExpression;
end;


procedure TOvcRvExp._CondPrimary
  (Parent: TOvcRvExpNode; var CondPrimary: TOvcRvExpCondPrimary);
var
  SimpleExpression :  TOvcRvExpSimpleExpression;
  RelOp            :  TOvcRvExpRelop;
  BetweenClause    :  TOvcRvExpBetweenClause;
  LikeClause       :  TOvcRvExpLikeClause;
  InClause         :  TOvcRvExpInClause;
  IsTest           :  TOvcRvExpIsTest;
begin
  CondPrimary := TOvcRvExpCondPrimary.Create(Parent);
  RelOp := roNone;
  _SimpleExpression(CondPrimary, SimpleExpression);
  CondPrimary.SimpleExp1 := SimpleExpression;
  if _In(symSet[4], fCurrentInputSymbol) then begin
    if _In(symSet[5], fCurrentInputSymbol) then begin
      if _In(symSet[6], fCurrentInputSymbol) then begin
        case fCurrentInputSymbol of
          _equalSym : begin
            Get;
            RelOp := roEQ;
          end;
          _less_equalSym : begin
            Get;
            RelOp := roLE;
          end;
          _lessSym : begin
            Get;
            RelOp := roL;
          end;
          _greaterSym : begin
            Get;
            RelOp := roG;
          end;
          _greater_equalSym : begin
            Get;
            RelOp := roGE;
          end;
          _less_greaterSym : begin
            Get;
            RelOp := roNE;
          end;
          else
            SynError(68);
        end;

        CondPrimary.RelOp := RelOp;
        _SimpleExpression(CondPrimary, SimpleExpression);
        CondPrimary.SimpleExp2 := SimpleExpression;
      end else if fCurrentInputSymbol = BETWEENSym then begin
        _BetweenClause(CondPrimary, BetweenClause, False);
        CondPrimary.BetweenClause := BetweenClause;
      end else if fCurrentInputSymbol = INSym then begin
        _InClause(CondPrimary, InClause, False);
        CondPrimary.InClause := InClause;
      end else if fCurrentInputSymbol = LIKESym then begin
        _LikeClause(CondPrimary, LikeClause, False);
        CondPrimary.LikeClause := LikeClause;
      end else if fCurrentInputSymbol = NOTSym then begin
        Get;
        if fCurrentInputSymbol = BETWEENSym then begin
          _BetweenClause(CondPrimary, BetweenClause, True);
          CondPrimary.BetweenClause := BetweenClause;
        end else if fCurrentInputSymbol = LIKESym then begin
          _LikeClause(CondPrimary, LikeClause, True);
          CondPrimary.LikeClause := LikeClause;
        end else
          SynError(69);
      end else
        SynError(70);
    end else begin
      _IsTest(CondPrimary, IsTest);
      CondPrimary.IsTest := IsTest;
      CondPrimary.RelOp := RoNone;
    end;
  end;
end;


procedure TOvcRvExp._CondFactor
  (Parent: TOvcRvExpNode; var CondFactor: TOvcRvExpCondFactor);
var
  CondPrimary: TOvcRvExpCondPrimary;
begin
  CondFactor := TOvcRvExpCondFactor.Create(Parent);
  if fCurrentInputSymbol = NOTSym then begin
    Get;
    CondFactor.UnaryNot := True;
  end;
  _CondPrimary(CondFactor, CondPrimary);
  CondFactor.CondPrimary := CondPrimary;
end;


procedure TOvcRvExp._CondTerm
  (Parent: TOvcRvExpNode; var CondTerm: TOvcRvExpCondTerm);
var
  CondFactor:  TOvcRvExpCondFactor;
begin
  CondTerm := TOvcRvExpCondTerm.Create(Parent);
  _CondFactor(CondTerm, CondFactor);
  CondTerm.AddCondFactor(CondFactor);
  while fCurrentInputSymbol = ANDSym do begin
    Get;
    _CondFactor(CondTerm, CondFactor);
    CondTerm.AddCondFactor(CondFactor);
  end;
end;


procedure TOvcRvExp._CondExpList
  (Parent: TOvcRvExpNode; var CondExpList: TOvcRvExpressionList);
var
  CondExp: TOvcRvExpression;
begin
  CondExpList := TOvcRvExpressionList.Create(Parent);
  _CondExp(CondExpList, CondExp);
  CondExpList.AddExpression(CondExp);
  while fCurrentInputSymbol = _commaSym do begin
    Get;
    _CondExp(CondExpList, CondExp);
    CondExpList.AddExpression(CondExp);
  end;
end;


procedure TOvcRvExp._FieldRef (Parent: TOvcRvExpNode;  var FieldRef: TOvcRvExpFieldRef);
begin
  FieldRef := TOvcRvExpFieldRef.Create(Parent);;
  Expect(identSym);
  FieldRef.FieldName := LexString;
end;


procedure TOvcRvExp._SimpleExpression
  (Parent: TOvcRvExpNode; var SimpleExpression: TOvcRvExpSimpleExpression);
var
  Term : TOvcRvExpTerm;
  AO   : TOvcRvExpAddOp;
begin
  SimpleExpression := TOvcRvExpSimpleExpression.Create(Parent);
  _Term(SimpleExpression, Term, aoPlus);
  SimpleExpression.AddTerm(Term);
  while (fCurrentInputSymbol = _plusSym) OR
        (fCurrentInputSymbol = _minusSym) OR
        (fCurrentInputSymbol = _bar_barSym) do begin
    if fCurrentInputSymbol = _plusSym then begin
      Get;
      AO := aoPlus;
    end else if fCurrentInputSymbol = _minusSym then begin
      Get;
      AO := aoMinus;
    end else begin
      Get;
      AO := aoConcat;
    end;
    _Term(SimpleExpression, Term, AO);
    SimpleExpression.AddTerm(Term);
  end;
end;


procedure TOvcRvExp._Aggregate
  (Parent: TOvcRvExpNode;  var Aggregate: TOvcRvExpAggregate);
var
  SimpleExpression: TOvcRvExpSimpleExpression;
begin
  Aggregate := TOvcRvExpAggregate.Create(Parent);
  if fCurrentInputSymbol = COUNTSym then begin
    Get;
    Expect(_lparenSym);
    Expect(_starSym);
    Expect(_rparenSym);
    Aggregate.AgFunction := agCount;
  end else if (fCurrentInputSymbol = MINSym) OR
              (fCurrentInputSymbol = MAXSym) OR
              (fCurrentInputSymbol = SUMSym) OR
              (fCurrentInputSymbol = AVGSym) then begin
    if fCurrentInputSymbol = MINSym then begin
      Get;
      Aggregate.AgFunction := agMin;
    end else if fCurrentInputSymbol = MAXSym then begin
      Get;
      Aggregate.AgFunction := agMax;
    end else if fCurrentInputSymbol = SUMSym then begin
      Get;
      Aggregate.AgFunction := agSum;
    end else begin
      Get;
      Aggregate.AgFunction := agAvg;
    end;
    Expect(_lparenSym);
    _SimpleExpression(Aggregate, SimpleExpression);
    Aggregate.SimpleExpression := SimpleExpression;
    if Aggregate.SimpleExpression.IsAggregateExpression then
      SynError(201);
    Expect(_rparenSym);
  end else
    SynError(71);
end;


procedure TOvcRvExp._CondExp
  (Parent: TOvcRvExpNode; var CondExp: TOvcRvExpression);
var
  CondTerm : TOvcRvExpCondTerm;
begin
  CondExp := TOvcRvExpression.Create(Parent);
  _CondTerm(CondExp, CondTerm);
  CondExp.AddCondTerm(CondTerm);
  while fCurrentInputSymbol = ORSym do begin
    Get;
    _CondTerm(CondExp, CondTerm);
    CondExp.AddCondTerm(CondTerm);
  end;
end;


procedure TOvcRvExp._OvcRvExp;
var
  Expression:  TOvcRvExpression;
begin
  Init;
  _CondExp(nil, Expression);
  RootNode := Expression;
  if fCurrentInputSymbol <> EOFSYMB then
    SynError(200);
  Final;
  if GetScanner.fLastCommentList.Count > 0 then begin
    if Assigned(fInternalGrammarComment) then
      fInternalGrammarComment(Self,GetScanner.fLastCommentList);
    GetScanner.fLastCommentList.Clear;
  end;
end;


function TOvcRvExp.GetMajorVersion : integer;
begin
  Result := 0;
end;


function TOvcRvExp.GetMinorVersion : integer;
begin
  Result := 0;
end;


function TOvcRvExp.GetRelease : integer;
begin
  Result := 0;
end;


function TOvcRvExp.GetBuild : integer;
begin
  Result := 31;
end;


function TOvcRvExp.GetBuildDate : TDateTime;
const
  BDate = 37029;
  Hour = 20;
  Min = 37;
begin
  Result := BDate + EncodeTime(Hour, Min, 0 ,0);
end;


function TOvcRvExp.GetVersion : string;
var
  MinorVersionStr : string;
begin
  MinorVersionStr := IntToStr(MinorVersion);
  if (length(MinorVersionStr) > 0) AND (MinorVersion > 0) then
    MinorVersionStr := '0' + MinorVersionStr;
  Result := 'Version: ' + IntToStr(MajorVersion) + '.' + MinorVersionStr + ' Release '
     + IntToStr(Release) + ' Build ' + IntToStr(Build);
end;


procedure TOvcRvExp.SetVersion(const Value : string);
begin
  // This is a read only property. However, we want the value
  // to appear in the Object Inspector during design time.
end;


procedure TOvcRvExp.Parse;
begin
  errDist := minErrDist;
  GetScanner._Reset;
  Get;
  _OvcRvExp;
end;  {Parse}


procedure TOvcRvExp.InitSymSet;
begin
  symSet[ 0, 0] := [EOFSYMB];
  symSet[ 0, 1] := [];
  symSet[ 0, 2] := [];
  symSet[ 0, 3] := [];
  symSet[ 1, 0] := [identSym, integer_Sym, floatSym, SQLStringSym, COUNTSym,
                      _lparenSym, MINSym, MAXSym, SUMSym, AVGSym];
  symSet[ 1, 1] := [TRUESym-16, FALSESym-16];
  symSet[ 1, 2] := [_minusSym-32, CASESym-32, CHARACTER_underscoreLENGTHSym-32,
                      CHAR_underscoreLENGTHSym-32, LOWERSym-32, UPPERSym-32,
                      POSITIONSym-32, SUBSTRINGSym-32, TRIMSym-32];
  symSet[ 1, 3] := [FORMATNUMBERSym-48, FORMATDATETIMESym-48, INTTOHEXSym-48,
                      EXTERNSym-48, DATESym-48, TIMESym-48, TIMESTAMPSym-48];
  symSet[ 2, 0] := [integer_Sym, floatSym, SQLStringSym];
  symSet[ 2, 1] := [TRUESym-16, FALSESym-16];
  symSet[ 2, 2] := [];
  symSet[ 2, 3] := [DATESym-48, TIMESym-48, TIMESTAMPSym-48];
  symSet[ 3, 0] := [];
  symSet[ 3, 1] := [];
  symSet[ 3, 2] := [CASESym-32, CHARACTER_underscoreLENGTHSym-32,
                      CHAR_underscoreLENGTHSym-32, LOWERSym-32, UPPERSym-32,
                      POSITIONSym-32, SUBSTRINGSym-32, TRIMSym-32];
  symSet[ 3, 3] := [FORMATNUMBERSym-48, FORMATDATETIMESym-48, INTTOHEXSym-48,
                      EXTERNSym-48];
  symSet[ 4, 0] := [];
  symSet[ 4, 1] := [NOTSym-16, _equalSym-16, _less_equalSym-16, _lessSym-16,
                      _greaterSym-16, _greater_equalSym-16, _less_greaterSym-16,
                      ISSym-16, BETWEENSym-16, LIKESym-16, INSym-16];
  symSet[ 4, 2] := [];
  symSet[ 4, 3] := [];
  symSet[ 5, 0] := [];
  symSet[ 5, 1] := [NOTSym-16, _equalSym-16, _less_equalSym-16, _lessSym-16,
                      _greaterSym-16, _greater_equalSym-16, _less_greaterSym-16,
                      BETWEENSym-16, LIKESym-16, INSym-16];
  symSet[ 5, 2] := [];
  symSet[ 5, 3] := [];
  symSet[ 6, 0] := [];
  symSet[ 6, 1] := [_equalSym-16, _less_equalSym-16, _lessSym-16,
                      _greaterSym-16, _greater_equalSym-16, _less_greaterSym-16];
  symSet[ 6, 2] := [];
  symSet[ 6, 3] := [];
end; {InitSymSet}

end { OvcRvExp }.
